package com.naiterui.ehp.bs.agent.service.impl;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.naiterui.ehp.bp.bo.statistics.AsConsultRecordBO;
import com.naiterui.ehp.bp.bo.statistics.AsOrderRecordBO;
import com.naiterui.ehp.bp.bo.statistics.AsProductRecordBO;
import com.naiterui.ehp.bp.bo.statistics.AsRecipelRecordBO;
import com.naiterui.ehp.bp.domain.Doctor;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bs.agent.entity.AgAgentArea;
import com.naiterui.ehp.bs.agent.entity.AgArea;
import com.naiterui.ehp.bs.agent.entity.AsAgentInviteCount;
import com.naiterui.ehp.bs.agent.entity.AsAreaCount;
import com.naiterui.ehp.bs.agent.entity.AsOrderCount;
import com.naiterui.ehp.bs.agent.entity.AsProductCount;
import com.naiterui.ehp.bs.agent.entity.AsProviceCount;
import com.naiterui.ehp.bs.agent.entity.AsRecipelCount;
import com.naiterui.ehp.bs.agent.feign.ISearchFeignClient;
import com.naiterui.ehp.bs.agent.repository.IAgAgentAreaRepository;
import com.naiterui.ehp.bs.agent.repository.IAgAgentCustomRepository;
import com.naiterui.ehp.bs.agent.repository.IAgAreaRepository;
import com.naiterui.ehp.bs.agent.repository.IAgCustomSummaryRepository;
import com.naiterui.ehp.bs.agent.repository.IAsAgentInviteCountRepository;
import com.naiterui.ehp.bs.agent.repository.IAsAreaCountRepository;
import com.naiterui.ehp.bs.agent.repository.IAsOrderCountRepository;
import com.naiterui.ehp.bs.agent.repository.IAsProductCountRepository;
import com.naiterui.ehp.bs.agent.repository.IAsProviceCountRepository;
import com.naiterui.ehp.bs.agent.repository.IAsRecipelCountRepository;
import com.naiterui.ehp.bs.agent.service.IAsService;
import com.naiterui.ehp.bs.agent.vo.AgAgentAreaVO;
import com.naiterui.ehp.bs.agent.vo.AgentDoctorVO;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 经济人统计
 *
 * @author yangfuya
 * @since 2022/2/16
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AsServiceImpl implements IAsService {
    private final ISearchFeignClient searchFeignClient;
    private final IAsAgentInviteCountRepository asAgentInviteCountRepository;
    private final IAsOrderCountRepository asOrderCountRepository;
    private final IAsProductCountRepository asProductCountRepository;
    private final IAsRecipelCountRepository asRecipelCountRepository;
    private final IAgAgentCustomRepository agAgentCustomRepository;
    private final IAgCustomSummaryRepository agCustomSummaryRepository;
    private final IAgAgentAreaRepository agAgentAreaRepository;
    private final IAsAreaCountRepository asAreaCountRepository;
    private final IAsProviceCountRepository asProviceCountRepository;
    private final IAgAreaRepository agAreaRepository;

    @Override
    public void generateReport(String reportDate) throws BusinessException {
        Date generateDate;
        String yesterday;
        if (StrUtil.isBlank(reportDate)) {
            yesterday = getYesterday();
            generateDate = DateUtil.parseDate(yesterday);
        } else {
            generateDate = DateUtil.parseDate(reportDate);
            yesterday = reportDate;
        }
        // 查询前置数据
        List<AgAgentAreaVO> agentAreaList = getAgentAreaList();
        List<AgentDoctorVO> agentDoctorList = findDoctor();
        Map<Long, List<AgentDoctorVO>> agentDoctorMap =
            agentDoctorList.stream().collect(Collectors.groupingBy(AgentDoctorVO::getAgentId));

        List<AsConsultRecordBO> consultRecordIndex = searchFeignClient.findConsultRecordIndex(yesterday);
        List<AsRecipelRecordBO> recipelRecordIndex = searchFeignClient.findRecipelRecordIndex(yesterday);
        List<AsOrderRecordBO> orderRecordIndex = searchFeignClient.findOrderRecordIndex(yesterday);
        List<AsProductRecordBO> productRecordIndex = searchFeignClient.findProductRecordIndex(yesterday);
        // 1.先对问诊以医生id分组
        // 图文问诊
        Map<Long, List<AsConsultRecordBO>> consultMap =
            consultRecordIndex.stream().filter(c -> c.getConsultType() == AsConsultRecordBO.TYPE_CONSULT)
                .collect(Collectors.groupingBy(AsConsultRecordBO::getDoctorId));
        // 视频问诊
        Map<Long, List<AsConsultRecordBO>> videoMap =
            consultRecordIndex.stream().filter(c -> c.getConsultType() == AsConsultRecordBO.TYPE_VIDEO)
                .collect(Collectors.groupingBy(AsConsultRecordBO::getDoctorId));
        // 处方
        Map<Long, List<AsRecipelRecordBO>> recipelMap =
            recipelRecordIndex.stream().collect(Collectors.groupingBy(AsRecipelRecordBO::getDoctorId));
        // 订单
        Map<Long, List<AsOrderRecordBO>> orderMap =
            orderRecordIndex.stream().collect(Collectors.groupingBy(AsOrderRecordBO::getDoctorId));
        // 商品
        Map<Long, List<AsProductRecordBO>> productMap =
            productRecordIndex.stream().collect(Collectors.groupingBy(AsProductRecordBO::getDoctorId));

        // 2.插入处方相关数据
        List<AsRecipelCount> asRecipelCountList = new ArrayList<>();
        AsRecipelCount asRecipelCount;
        // 3.处理订单相关数据
        List<AsOrderCount> asOrderCountList = new ArrayList<>();
        AsOrderCount asOrderCount;
        // 4.处理商品相关数据
        List<AsProductCount> asProductCountList = new ArrayList<>();
        AsProductCount asProductCount;

        // 5.处理经纪人邀请医生数据
        List<AsAgentInviteCount> agentInviteCountList = new ArrayList<>();
        AsAgentInviteCount asAgentInviteCount;
        for (AgAgentAreaVO vo : agentAreaList) {
            Long areaId = vo.getAreaId();
            Long provinceAreaId = vo.getProviceAreaId();
            Long agentId = vo.getAgentId();
            List<AgentDoctorVO> list = agentDoctorMap.get(vo.getAgentId());
            if (CollUtil.isEmpty(list)) {
                continue;
            }
            for (AgentDoctorVO agentDoctor : list) {
                asRecipelCount = new AsRecipelCount();
                asOrderCount = new AsOrderCount();
                Long doctorId = agentDoctor.getDoctorId();

                asRecipelCount.setAreaId(areaId);
                asRecipelCount.setProvinceAreaId(provinceAreaId);
                asRecipelCount.setAgentId(agentId);
                asRecipelCount.setDoctorId(doctorId);
                asRecipelCount.setGenerateDate(generateDate);
                asRecipelCount.setCreatedBy("system");

                asOrderCount.setAreaId(areaId);
                asOrderCount.setProvinceAreaId(provinceAreaId);
                asOrderCount.setAgentId(agentId);
                asOrderCount.setDoctorId(doctorId);
                asOrderCount.setGenerateDate(generateDate);
                asOrderCount.setCreatedBy("system");

                List<AsConsultRecordBO> consults = consultMap.get(doctorId);
                if (CollUtil.isEmpty(consults)) {
                    asRecipelCount.setConsultTotal(0);
                    asRecipelCount.setConsultPriceTotal(0);
                } else {
                    asRecipelCount.setConsultTotal(consults.size());
                    asRecipelCount
                        .setConsultPriceTotal(consults.stream().mapToInt(AsConsultRecordBO::getConsultPrice).sum());
                }
                List<AsConsultRecordBO> videos = videoMap.get(doctorId);
                if (CollUtil.isEmpty(videos)) {
                    asRecipelCount.setVideoTotal(0);
                    asRecipelCount.setVideoPriceTotal(0);
                } else {
                    asRecipelCount.setVideoTotal(videos.size());
                    asRecipelCount
                        .setVideoPriceTotal(videos.stream().mapToInt(AsConsultRecordBO::getConsultPrice).sum());
                }

                List<AsRecipelRecordBO> recipels = recipelMap.get(doctorId);
                if (CollUtil.isEmpty(recipels)) {
                    asRecipelCount.setRecipelTotal(0);
                    asRecipelCount.setPaidNumber(0);
                    asRecipelCount.setUnpaidNumber(0);
                    asRecipelCount.setRepeatNumber(0);
                } else {
                    asRecipelCount.setRecipelTotal(recipels.size());
                    asRecipelCount.setPaidNumber((int)recipels.stream().filter(r -> r.getRecipelStatus() == 1).count());
                    asRecipelCount
                        .setUnpaidNumber((int)recipels.stream().filter(r -> r.getRecipelStatus() == 0).count());
                    asRecipelCount
                        .setRepeatNumber((int)recipels.stream().filter(r -> r.getRepeatStatus() == 1).count());
                }

                List<AsOrderRecordBO> orders = orderMap.get(doctorId);
                if (CollUtil.isEmpty(orders)) {
                    asRecipelCount.setOrderTotal(0);
                    asRecipelCount.setOrderPriceTotal(0);
                    asOrderCount.setOrderTotal(0);
                } else {
                    asRecipelCount.setOrderTotal(orders.size());
                    asRecipelCount.setOrderPriceTotal(orders.stream().mapToInt(AsOrderRecordBO::getOrderPrice).sum());
                    asOrderCount.setOrderTotal(orders.size());
                }
                List<AsProductRecordBO> products = productMap.get(doctorId);
                if (CollUtil.isNotEmpty(products)) {
                    for (AsProductRecordBO product : products) {
                        asProductCount = new AsProductCount();
                        asProductCount.setAreaId(areaId);
                        asProductCount.setProvinceAreaId(provinceAreaId);
                        asProductCount.setAgentId(agentId);
                        asProductCount.setDoctorId(doctorId);
                        asProductCount.setGenerateDate(generateDate);
                        asProductCount.setProductId(product.getProductId());
                        asProductCount.setProductNumber(product.getProductNumber());
                        asProductCount
                            .setProductPriceTotal(product.getProductPrice() == null ? 0 : product.getProductPrice());
                        asProductCountList.add(asProductCount);
                    }
                }
                asRecipelCountList.add(asRecipelCount);
                asOrderCountList.add(asOrderCount);
            }
            asAgentInviteCount = new AsAgentInviteCount();
            asAgentInviteCount.setAreaId(areaId);
            asAgentInviteCount.setProvinceAreaId(provinceAreaId);
            asAgentInviteCount.setAgentId(agentId);
            asAgentInviteCount.setGenerateDate(generateDate);
            asAgentInviteCount.setCreatedBy("system");
            List<AgentDoctorVO> doctors = agentDoctorMap.get(agentId);
            asAgentInviteCount.setNewNumber(0);
            asAgentInviteCount.setAuthNumber(0);
            asAgentInviteCount.setUnauthNumebr(0);
            asAgentInviteCount.setAuthingNumebr(0);
            asAgentInviteCount.setNoPassNumber(0);
            if (CollUtil.isNotEmpty(doctors)) {
                List<AgentDoctorVO> doctorVOList =
                    doctors.stream().filter(d -> d.getInviteDate().equals(yesterday)).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(doctorVOList)) {
                    asAgentInviteCount.setNewNumber(doctorVOList.size());
                    asAgentInviteCount.setAuthNumber(
                        (int)doctorVOList.stream().filter(d -> d.getStatus() == Doctor.AUTH_STATUS_SUCCESS).count());
                    asAgentInviteCount.setUnauthNumebr((int)doctorVOList.stream()
                        .filter(d -> d.getStatus() == Doctor.AUTH_STATUS_NOT_PERFECTION).count());
                    asAgentInviteCount.setAuthingNumebr(
                        (int)doctorVOList.stream().filter(d -> d.getStatus() == Doctor.AUTH_STATUS_AUDITING).count());
                    asAgentInviteCount.setNoPassNumber(
                        (int)doctorVOList.stream().filter(d -> d.getStatus() == Doctor.AUTH_STATUS_REJECTED).count());
                }
            }
            agentInviteCountList.add(asAgentInviteCount);
        }

        String generateDateStr = DateUtil.formatDate(generateDate);
        try {
            AsRecipelCount recipelCount = asRecipelCountRepository.getTotalByGenerateDate(generateDateStr);
            if (recipelCount == null) {
                asRecipelCountRepository.saveAll(asRecipelCountList);
            }
        } catch (Exception e) {
            log.info("插入处方相关统计时出现异常：{}, e: {}", JSONUtil.toJsonStr(asRecipelCountList), e.getMessage());
        }
        try {
            AsOrderCount orderCount = asOrderCountRepository.getTotalByGenerateDate(generateDateStr);
            if (orderCount == null) {
                asOrderCountRepository.saveAll(asOrderCountList);
            }
        } catch (Exception e) {
            log.info("插入订单相关统计时出现异常：{}, e: {}", JSONUtil.toJsonStr(asOrderCountList), e.getMessage());
        }
        try {
            AsProductCount productCount = asProductCountRepository.getTotalByGenerateDate(generateDateStr);
            if (productCount == null) {
                asProductCountRepository.saveAll(asProductCountList);
            }
        } catch (Exception e) {
            log.info("插入商品售卖统计时出现异常：{}, e: {}", JSONUtil.toJsonStr(asProductCountList), e.getMessage());
        }
        try {
            AsAgentInviteCount inviteCount = asAgentInviteCountRepository.getTotalByGenerateDate(generateDateStr);
            if (inviteCount == null) {
                asAgentInviteCountRepository.saveAll(agentInviteCountList);
            }
        } catch (Exception e) {
            log.info("插入经纪人邀请医生统计时出现异常：{}, e: {}", JSONUtil.toJsonStr(agentInviteCountList), e.getMessage());
        }
        log.info("每日生成报表条数，recipelCount: {}, orderCount: {}, productCount:{}, agentInviteCount: {}",
            asRecipelCountList.size(), asOrderCountList.size(), asProductCountList.size(), agentInviteCountList.size());

        // 处理区域数据
        try {
            AsAreaCount areaCount = asAreaCountRepository.getTotalByGenerateDate(generateDateStr);
            if (areaCount == null) {
                this.saveAreaProviceCount(generateDate, agentAreaList, asRecipelCountList, agentInviteCountList);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("插入区域数据统计时出现异常 e: {}", e.getMessage());
        }
    }

    /**
     * 保存大区和省区数据
     */
    private void saveAreaProviceCount(Date generateDate, List<AgAgentAreaVO> agentAreaList,
        List<AsRecipelCount> asRecipelCountList, List<AsAgentInviteCount> agentInviteCountList) {
        String yesterday = DateUtil.formatDate(generateDate);
        log.info(
            "save area count, generateDate: {}, agentAreaList: {}, asRecipelCountList: {}, agentInviteCountList: {}",
            generateDate, agentAreaList.size(), asRecipelCountList.size(), agentInviteCountList.size());

        Map<Long, List<AgAgentAreaVO>> agentMap =
            agentAreaList.stream().collect(Collectors.groupingBy(AgAgentAreaVO::getProviceAreaId));

        // 获取区域
        List<AgArea> areaList = agAreaRepository.findAllByAreaLev(AgAgentArea.AREA_LEV_PROVINCE);

        // 查询昨日区域数据
        List<AsAreaCount> areaYesterday = asAreaCountRepository.getYesterday(yesterday);
        Map<Long, AsAreaCount> areaYesterdayMap =
            areaYesterday.stream().collect(Collectors.toMap(AsAreaCount::getProvinceAreaId, a -> a));

        // 查询昨日省份数据
        List<AsProviceCount> proviceYesterday = asProviceCountRepository.getYesterday(yesterday);
        Map<Long, AsProviceCount> proviceYesterdayMap =
            proviceYesterday.stream().collect(Collectors.toMap(AsProviceCount::getProvinceAreaId, a -> a));

        // 处理业务数据
        Map<Long, List<AsRecipelCount>> recipelMap =
            asRecipelCountList.stream().collect(Collectors.groupingBy(AsRecipelCount::getProvinceAreaId));
        Map<Long, List<AsAgentInviteCount>> inviteMap =
            agentInviteCountList.stream().collect(Collectors.groupingBy(AsAgentInviteCount::getProvinceAreaId));

        // 所有经纪人数量
        List<AsAreaCount> areaCountList = new ArrayList<>();
        List<AsProviceCount> proviceCountList = new ArrayList<>();
        AsAreaCount areaCount;
        AsProviceCount proviceCount;
        for (AgArea a : areaList) {
            areaCount = new AsAreaCount();
            proviceCount = new AsProviceCount();

            Long provinceAreaId = a.getId();
            Long areaId = a.getParentId();
            if (areaId == null) {
                areaCount.setAreaId(0L);
            } else {
                areaCount.setAreaId(areaId);
            }
            areaCount.setProvinceAreaId(provinceAreaId);
            areaCount.setGenerateDate(generateDate);

            proviceCount.setProvinceAreaId(provinceAreaId);
            proviceCount.setGenerateDate(generateDate);

            // 处理处方
            List<AsRecipelCount> recipelCounts = recipelMap.get(provinceAreaId);
            int recipelTotal = 0;
            int paidNumber = 0;
            int unpaidNumber = 0;
            int repeatNumber = 0;
            int consultTotal = 0;
            int consultPriceTotal = 0;
            int videoTotal = 0;
            int videoPriceTotal = 0;
            int orderTotal = 0;
            int orderPriceTotal = 0;
            if (CollUtil.isNotEmpty(recipelCounts)) {
                recipelTotal = recipelCounts.stream().mapToInt(AsRecipelCount::getRecipelTotal).sum();
                paidNumber = recipelCounts.stream().mapToInt(AsRecipelCount::getPaidNumber).sum();
                unpaidNumber = recipelCounts.stream().mapToInt(AsRecipelCount::getUnpaidNumber).sum();
                repeatNumber = recipelCounts.stream().mapToInt(AsRecipelCount::getRepeatNumber).sum();
                consultTotal = recipelCounts.stream().mapToInt(AsRecipelCount::getConsultTotal).sum();
                consultPriceTotal = recipelCounts.stream().mapToInt(AsRecipelCount::getConsultPriceTotal).sum();
                videoTotal = recipelCounts.stream().mapToInt(AsRecipelCount::getVideoTotal).sum();
                videoPriceTotal = recipelCounts.stream().mapToInt(AsRecipelCount::getVideoPriceTotal).sum();
                orderTotal = recipelCounts.stream().mapToInt(AsRecipelCount::getOrderTotal).sum();
                orderPriceTotal = recipelCounts.stream().mapToInt(AsRecipelCount::getOrderPriceTotal).sum();
            }
            areaCount.setRecipelTotal(recipelTotal);
            areaCount.setPaidNumber(paidNumber);
            areaCount.setUnpaidNumber(unpaidNumber);
            areaCount.setRepeatNumber(repeatNumber);
            areaCount.setConsultTotal(consultTotal);
            areaCount.setConsultPriceTotal(consultPriceTotal);
            areaCount.setVideoTotal(videoTotal);
            areaCount.setVideoPriceTotal(videoPriceTotal);
            areaCount.setOrderTotal(orderTotal);
            areaCount.setOrderPriceTotal(orderPriceTotal);

            // 处理邀请医生
            List<AsAgentInviteCount> agentInviteCounts = inviteMap.get(provinceAreaId);
            int newNumber = 0;
            int authNumber = 0;
            int unauthNumebr = 0;
            int authingNumebr = 0;
            int noPassNumber = 0;
            if (CollUtil.isNotEmpty(agentInviteCounts)) {
                newNumber = agentInviteCounts.stream().mapToInt(AsAgentInviteCount::getNewNumber).sum();
                authNumber = agentInviteCounts.stream().mapToInt(AsAgentInviteCount::getAuthNumber).sum();
                unauthNumebr = agentInviteCounts.stream().mapToInt(AsAgentInviteCount::getUnauthNumebr).sum();
                authingNumebr = agentInviteCounts.stream().mapToInt(AsAgentInviteCount::getAuthingNumebr).sum();
                noPassNumber = agentInviteCounts.stream().mapToInt(AsAgentInviteCount::getNoPassNumber).sum();
            }
            areaCount.setNewNumber(newNumber);
            areaCount.setAuthNumber(authNumber);
            areaCount.setUnauthNumebr(unauthNumebr);
            areaCount.setAuthingNumebr(authingNumebr);
            areaCount.setNoPassNumber(noPassNumber);

            // 处理下属总人数
            List<AgAgentAreaVO> list = agentMap.get(provinceAreaId);
            int agentTotal = 0;
            if (CollUtil.isNotEmpty(list)) {
                agentTotal =
                    list.stream().filter(aa -> DateUtil.formatDate(aa.getCreatedAt()).equals(yesterday))
                        .collect(Collectors.toList()).size();
            }
            areaCount.setAgentTotal(agentTotal);

            // 处理省份数据
            int proviceRecipelTotal = recipelTotal;
            int provicePaidNumber = paidNumber;
            int proviceUnpaidNumber = unpaidNumber;
            int proviceRepeatNumber = repeatNumber;
            int proviceConsultTotal = consultTotal;
            int proviceConsultPriceTotal = consultPriceTotal;
            int proviceVideoTotal = videoTotal;
            int proviceVideoPriceTotal = videoPriceTotal;
            int proviceOrderTotal = orderTotal;
            int privceOrderPriceTotal = orderPriceTotal;
            int proviceNewNumber = newNumber;
            int proviceAuthNumber = authNumber;
            int proviceUnauthNumebr = unauthNumebr;
            int proviceAuthingNumebr = authingNumebr;
            int proviceNoPassNumber = noPassNumber;
            int proviceAgentTotal = agentTotal;
            AsAreaCount asAreaCount = areaYesterdayMap.get(provinceAreaId);
            AsProviceCount asProviceCount = proviceYesterdayMap.get(provinceAreaId);
            if (asProviceCount != null) {
                proviceRecipelTotal = recipelTotal + asProviceCount.getRecipelTotal();
                provicePaidNumber = paidNumber + asProviceCount.getPaidNumber();
                proviceUnpaidNumber = unpaidNumber + asProviceCount.getUnpaidNumber();
                proviceRepeatNumber = repeatNumber + asProviceCount.getRepeatNumber();
                proviceConsultTotal = consultTotal + asProviceCount.getConsultTotal();
                proviceConsultPriceTotal = consultPriceTotal + asProviceCount.getConsultPriceTotal();
                proviceVideoTotal = videoTotal + asProviceCount.getVideoTotal();
                proviceVideoPriceTotal = videoPriceTotal + asProviceCount.getVideoPriceTotal();
                proviceOrderTotal = orderTotal + asProviceCount.getOrderTotal();
                privceOrderPriceTotal = orderPriceTotal + asProviceCount.getOrderPriceTotal();
                proviceNewNumber = newNumber + asProviceCount.getNewNumber();
                proviceAuthNumber = authNumber + asProviceCount.getAuthNumber();
                proviceUnauthNumebr = unauthNumebr + asProviceCount.getUnauthNumebr();
                proviceAuthingNumebr = authingNumebr + asProviceCount.getAuthingNumebr();
                proviceNoPassNumber = noPassNumber + asProviceCount.getNoPassNumber();
                proviceAgentTotal = proviceAgentTotal + asProviceCount.getAgentTotal();
                if (asAreaCount != null) {
                    proviceRecipelTotal = proviceRecipelTotal + asAreaCount.getRecipelTotal();
                    provicePaidNumber = -provicePaidNumber + asAreaCount.getPaidNumber();
                    proviceUnpaidNumber = proviceUnpaidNumber + asAreaCount.getUnpaidNumber();
                    proviceRepeatNumber = proviceRepeatNumber + asAreaCount.getRepeatNumber();
                    proviceConsultTotal = proviceConsultTotal + asAreaCount.getConsultTotal();
                    proviceConsultPriceTotal = proviceConsultPriceTotal + asAreaCount.getConsultPriceTotal();
                    proviceVideoTotal = proviceVideoTotal + asAreaCount.getVideoTotal();
                    proviceVideoPriceTotal = proviceVideoPriceTotal + asAreaCount.getVideoPriceTotal();
                    proviceOrderTotal = proviceOrderTotal + asAreaCount.getOrderTotal();
                    privceOrderPriceTotal = privceOrderPriceTotal + asAreaCount.getOrderPriceTotal();
                    proviceNewNumber = proviceNewNumber + asAreaCount.getNewNumber();
                    proviceAuthNumber = proviceAuthNumber + asAreaCount.getAuthNumber();
                    proviceUnauthNumebr = proviceUnauthNumebr + asAreaCount.getUnauthNumebr();
                    proviceAuthingNumebr = proviceAuthingNumebr + asAreaCount.getAuthingNumebr();
                    proviceNoPassNumber = proviceNoPassNumber + asAreaCount.getNoPassNumber();
                    proviceAgentTotal = proviceAgentTotal + asAreaCount.getAgentTotal();
                }
            }
            areaCount.setOldAreaId(0L);
            if (asAreaCount != null) {
                if (!asAreaCount.getAreaId().equals(areaId)) {
                    areaCount.setOldAreaId(asAreaCount.getAreaId());
                    proviceRecipelTotal = proviceRecipelTotal - asAreaCount.getRecipelTotal();
                    provicePaidNumber = -provicePaidNumber - asAreaCount.getPaidNumber();
                    proviceUnpaidNumber = proviceUnpaidNumber - asAreaCount.getUnpaidNumber();
                    proviceRepeatNumber = proviceRepeatNumber - asAreaCount.getRepeatNumber();
                    proviceConsultTotal = proviceConsultTotal - asAreaCount.getConsultTotal();
                    proviceConsultPriceTotal = proviceConsultPriceTotal - asAreaCount.getConsultPriceTotal();
                    proviceVideoTotal = proviceVideoTotal - asAreaCount.getVideoTotal();
                    proviceVideoPriceTotal = proviceVideoPriceTotal - asAreaCount.getVideoPriceTotal();
                    proviceOrderTotal = proviceOrderTotal - asAreaCount.getOrderTotal();
                    privceOrderPriceTotal = privceOrderPriceTotal - asAreaCount.getOrderPriceTotal();
                    proviceNewNumber = proviceNewNumber - asAreaCount.getNewNumber();
                    proviceAuthNumber = proviceAuthNumber - asAreaCount.getAuthNumber();
                    proviceUnauthNumebr = proviceUnauthNumebr - asAreaCount.getUnauthNumebr();
                    proviceAuthingNumebr = proviceAuthingNumebr - asAreaCount.getAuthingNumebr();
                    proviceNoPassNumber = proviceNoPassNumber - asAreaCount.getNoPassNumber();
                    proviceAgentTotal = proviceAgentTotal - asAreaCount.getAgentTotal();
                }
            }
            proviceCount.setRecipelTotal(proviceRecipelTotal);
            proviceCount.setPaidNumber(provicePaidNumber);
            proviceCount.setUnpaidNumber(proviceUnpaidNumber);
            proviceCount.setRepeatNumber(proviceRepeatNumber);
            proviceCount.setConsultTotal(proviceConsultTotal);
            proviceCount.setConsultPriceTotal(proviceConsultPriceTotal);
            proviceCount.setVideoTotal(proviceVideoTotal);
            proviceCount.setVideoPriceTotal(proviceVideoPriceTotal);
            proviceCount.setOrderTotal(proviceOrderTotal);
            proviceCount.setOrderPriceTotal(privceOrderPriceTotal);
            proviceCount.setNewNumber(proviceNewNumber);
            proviceCount.setAuthNumber(proviceAuthNumber);
            proviceCount.setUnauthNumebr(proviceUnauthNumebr);
            proviceCount.setAuthingNumebr(proviceAuthingNumebr);
            proviceCount.setNoPassNumber(proviceNoPassNumber);
            proviceCount.setAgentTotal(proviceAgentTotal);

            areaCountList.add(areaCount);
            proviceCountList.add(proviceCount);
        }
        log.info("save all area count list size : {} and provice count list size : {}", areaCountList.size(),
            proviceCountList.size());
        asAreaCountRepository.saveAll(areaCountList);
        asProviceCountRepository.saveAll(proviceCountList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void generateSummaryReport() {
        try {
            // 生成客户汇总统计
            agCustomSummaryRepository.deleteAllData();
            agCustomSummaryRepository.insertCustomSummary();
        }catch (Exception e){
            log.error("保存客户汇总数据异常", e);
        }
    }

    private List<AgAgentAreaVO> getAgentAreaList() {
        List<AgAgentAreaVO> agentAreaList = new ArrayList<>();
        List<Object[]> objects = agAgentAreaRepository.findAllByTitleType();
        AgAgentAreaVO agent;
        for (Object[] obj : objects) {
            agent = new AgAgentAreaVO();
            agent.setAreaId(obj[0] == null ? 0L : Long.parseLong(obj[0].toString()));
            agent.setProviceAreaId(obj[1] == null ? 0L : Long.parseLong(obj[1].toString()));
            agent.setAgentId(obj[2] == null ? 0L : Long.parseLong(obj[2].toString()));
            agent.setCreatedAt((Date)obj[3]);
            agentAreaList.add(agent);
        }
        return agentAreaList;
    }

    public List<AgentDoctorVO> findDoctor() {
        List<AgentDoctorVO> list = new ArrayList<>();
        List<Object[]> rs = agAgentCustomRepository.findDoctor();
        AgentDoctorVO agent;
        for (Object[] obj : rs) {
            agent = new AgentDoctorVO();
            agent.setAreaId(obj[0] == null ? 0L : Long.parseLong(obj[0].toString()));
            agent.setProvinceAreaId(obj[1] == null ? 0L : Long.parseLong(obj[1].toString()));
            agent.setAgentId(obj[2] == null ? 0L : Long.parseLong(obj[2].toString()));
            agent.setDoctorId(obj[3] == null ? 0L : Long.parseLong(obj[3].toString()));
            agent.setStatus(obj[4] == null ? 0 : Integer.valueOf(obj[4].toString()));
            agent.setInviteDate(obj[5] == null ? "" : obj[5].toString());
            list.add(agent);
        }
        return list;
    }

    private String getYesterday() {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, -24);
        return dateFormat.format(calendar.getTime());
    }
}
